package main;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class World {
	public int qtdPonto;
	public int qtdEstacao;
	public List<Estacao> estacoes;


	public World(){
		this.estacoes = new ArrayList<Estacao>();

	}
	
	public World(int N, int M, List<Estacao> estacoes) {
		this.qtdPonto = N;
		this.qtdEstacao = M;
		this.estacoes = estacoes;

	}
	
	public World(String arquivo) {
		this.estacoes = new ArrayList<Estacao>();
		lerArquivo(arquivo);
	}
	
	//Setters and Getters

	public int getN() {
		return qtdPonto;
	}

	public void setN(int n) {
		qtdPonto = n;
	}

	public int getM() {
		return qtdEstacao;
	}

	public void setM(int m) {
		qtdEstacao = m;
	}

	public List<Estacao> getEstacoes() {
		return estacoes;
	}

	public void setEstacoes(List<Estacao> estacoes) {
		this.estacoes = estacoes;
	}

	/**
	 * Le do arquivo de entrada os aprametros necessarios e monda o objeto world
	 * @param leitor
	 */
	public void lerArquivo(String arquivo) {
		String linha = null;
		try {
			FileReader fr = new FileReader(arquivo);
			BufferedReader leitor = new BufferedReader(fr);
			
			//le primeira linha
			linha = leitor.readLine();
			this.qtdPonto = lerMN(linha);
			
			//le segunda linha
			linha = leitor.readLine();
			this.qtdEstacao = lerMN(linha);
			
			//le as estacoes
			linha = leitor.readLine();
			//linha inicial das estacoes eh a linha 3 do arquivo
			//dessa forma: S1(linha 3), S2(linha 4), ... SN(linha N+2)
			//S1 -> indice 0, S2 -> indice 1, ... SN -> indice N-1
			while (linha != null) {
				Estacao e = lerEstacao(linha);
				this.estacoes.add(e);
				linha = leitor.readLine();
			}
			
			leitor.close();
			fr.close();
		} catch (FileNotFoundException e ){
			System.out.println("Arquivo nao encontrado.");
		} catch (IOException e) {
			System.out.println("Erro na leitura do arquivo.");
		}
	}

	/**
	 * Le o valor de M ou N e retorna como inteiro
	 * 
	 * @param String
	 *            linha
	 * @return valor inteiro de M ou N
	 */
	public int lerMN(String linha) {
		String[] parts = linha.split(" ");
		return Integer.parseInt(parts[1]);
	}

	/**
	 * Separa de uma linha as partes da estacao
	 * 
	 * @param linha
	 * @return objeto Estacao
	 */
	public Estacao lerEstacao(String linha) {
		String[] parts = linha.split(" ");
		Estacao e = new Estacao();

		// Nome
		e.setNome(parts[0]);
		// Custo
		e.setCusto(Double.parseDouble(parts[1]));

		// aqui armazenarah lista (com tamanho igual ao numero pontos a serem cobertos)
		// com true na posicao i caso o ponto i+1 seja coberto pela estacao, false caso contrario
		//inicia lista com todas as posicoes como false
		List<Boolean> list = new ArrayList<Boolean>();
		for (int j = 0; j < this.qtdEstacao; j++)
			list.add(j,false); 
		
		// percorre a lista de pontos cobertos passados na entrada
		for(int i = 2; i < parts.length; i++) {
			//insere true nos indices = value(parts[i]) - 1 da lista de pontos cobertos
			list.set(Integer.parseInt(parts[i]) - 1, true);
		}
		
		//adiciona lista de pontos cobertos ah estacao
		e.setPontos(list);

		return e;
	}

	/**
	 * 
	 * @param lista
	 * @return custo total da escolhas de estacoes
	 */
	public double calculaCustoTotal(List<Estacao> lista) {
		Iterator<Estacao> ir = lista.iterator();
		Estacao e;
		double total = 0.0;
		while (ir.hasNext()) {
			e = (Estacao) ir.next();
			total += e.getCusto();
		}
		return total;
	}
	
	/**
	 * Escreve a solucao no arquivo
	 * @param arquivo
	 */
	/*
	public void escreveSolucao(String arquivo){
		try {
			FileWriter writer = new FileWriter(arquivo);
			PrintWriter saida = new PrintWriter(writer);  
			saida.println("Valor: " + calculaCustoTotal(this.escolhas));
			saida.println("Total: " + this.escolhas.size());
			for(Estacao e : this.escolhas){
				saida.println(e.getNome());	
			}
			saida.close();
			writer.close();
		} catch (IOException e) {
			System.out.println("Erro ao escrever no arquivo.");
		}
		
	}
	*/
	public void imprimeMundo(){
		System.out.println("M: " + this.qtdEstacao);
		System.out.println("N: " + this.qtdPonto);
		System.out.println("Estacoes: " + this.estacoes);
	}
	
	//TODO
	public String toString(){
		return "M: " + this.qtdPonto + "\n" +
			"N: " + this.qtdEstacao + "\n" +
			"Estacoes: " + this.estacoes.toString() +
			"\n";
	}
	

}
